When you employ IPC in your LScript, the LScript engine creates, on your script's behalf, an internal list of message "slots.". Your LScript then becomes the designated owner of this list. Although the creator of a messaging area effectively becomes its "owner", once it exists, other LScripts can "attach" to this list. Through coordinated access, these "slots" can be populated with script-related data, which can then be read by other scripts.
To use LScript's IPC mechanism, you simply designate a holding area, known as a
"queue", where any number of identified slots will exist. Each queue you wish
to create is declared using the expose
command:
expose <slot identifier(s)> as <queue identifier>;Slot identifiers provided to
expose
become indirect pointers into
the queue's data storage areas. Once a queue has been created, the owner of
the queue can access and update these slot values by using the slot identifiers
as though they were global variables declared within the scope of your script:
expose MakeObject, ObjectFile as MyQueue; ... ObjectFile = nil; // a queue slot if(MakeObject != nil) { ...Other LScript instances that need to access your IPC queue slots need only specify the name of the queue and the slot within that queue, separated by a dollar sign character ('$'). This mechanism can also be employed by the owner of the queue, but is only required when you have multiple queues that contain slots that use the same identifier. Preceeding the slot identifier with the queue name is needed to remove the ambiguity; if you do not provide it, LScript will use the first slot with that identifier that it can locate.
Were we in another script that needed to access the data value contained by
one of the slots in the MyQueue
queue, we could access it
quite quickly and simply in the following fashion:
... v1 = MyQueue$ObjectFile; ...The IPC mechanism will automatically ensure that access to slot values does not take place by more than one requester at a time. If two scripts try to access a slot at the same (CPU) time, one will be forced to wait until the slot has been read/updated by the first requester to lock the slot.
If a queue/slot combination does not exist, or has not yet been initialized
with data, then the value returned by any read access is always 'nil
'.
expose objects[100] as MyQueue; ...As with regular queue variables, you simply acess array elements within your script as though they were local variables:
... for(x = 1;x <= 100;x++) objects[x] = <0,0,0>;You can also utilize pre-processor macros in your construction of queue arrays:
@insert "lights.inc" ... // 'TOTALLIGHTS' defined as 75 in "lights.inc" expose light[TOTALLIGHTS] as LightQueue; ... for(x = 1;x <= TOTALLIGHTS;x++) light[x] = <0,0,0>;Please note that each queue array element is essentially a queue slot entry, and that there is a practical limit on the number of slot entries that can be created by any single process. This limit is dictated by the operating system under which the script is being executed. Be conservative in your use of queue arrays.
The "master" script creates an IPC queue where it will post its position, frame by frame, for slave objects to access and process:
@warnings // this "expose" command creates an IPC queue called "Master" with one // slot, 'position' expose position as Master; create { setdesc("Channel-lock Demo - Master Object"); } process: ma, frame, time { position = ma.get(POSITION,time); // we could have explicity identified the queue in the assignment, if // we had wanted more verbiage, or needed to identify a specific queue // slot: // // Master$position = ma.get(POSITION,time); }Here is a "slave" script that will query the
Master
queue
to acquire the master script's position, matching its X-motion channel
to that of the primary object:
@warnings create { setdesc("Channel-lock Demo - X-Axis Slave"); } process: ma, frame, time { pos = ma.get(POSITION,time); newpos = Master$position; // access Master's queue if(newpos == nil) // if something's wrong, recover gracefully ma.set(POSITION,pos); else ma.set(POSITION,<newpos.x,pos.y,pos.z>); }When these two scripts are attached to objects within Layout, only one object (the "master") needs to have keyframed animation. The "slave" object will move automatically along the X axis, matching its position frame-by-frame to that of the master. The order in which to load everything into Layout to achieve this effect is as follows:
1. Load the "master" object 2. Associate the "master" LScript with that object and activate it 3. Load the "slave" object (so that it appears *after* the master in the object list) 4. Associate the "slave" LScript with that object and activate it
string (up to 255 characters) number vector 'nil'More complex data types may become eligible for IPC transport as the mechanism evolves.